// Prevents additional console window on Windows in release, DO NOT REMOVE!!
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]

mod types;
mod screenshot_local;
mod clipboard;
mod img_utils;
mod save_to_file;

use crate::screenshot_local::{ScreenTarget, screenshot_to_img, capture_region};
use crate::types::TResult;
use image::{DynamicImage, ImageFormat};

use chrono::Local;

#[derive(serde::Serialize, serde::Deserialize, Clone, Debug)]
enum SupportedFormat {
    Png,
    Jpeg,
    WebP,
    Bmp,
    Tiff,
}

#[derive(serde::Serialize, serde::Deserialize, Clone, Debug)]
enum ScreenshotMode {
    Fullscreen,
    Region,
}

#[derive(serde::Serialize, serde::Deserialize, Clone, Debug)]
struct Region {
    x: i32,
    y: i32,
    width: u32,
    height: u32,
}

#[derive(serde::Serialize, serde::Deserialize, Debug, Clone)]
struct SaveOptions {
    format: SupportedFormat,
    quality: Option<u8>, // 1-100, 仅用于JPEG和WebP
    hide_window: Option<bool>, // 是否在截图时隐藏窗口
    mode: Option<ScreenshotMode>, // 截图模式：全屏或区域
    region: Option<Region>, // 区域截图的坐标和尺寸
    save_to_clipboard: Option<bool>, // 是否保存到剪贴板
    save_to_file: Option<bool>, // 是否保存到文件
    file_path: Option<String>, // 文件保存路径
}

#[derive(serde::Serialize, serde::Deserialize)]
struct ScreenshotResult {
    success: bool,
    message: String,
    path: Option<String>,
    base64_data: Option<String>,
}

#[derive(serde::Serialize, serde::Deserialize, Clone, Debug)]
struct SelectionResult {
    x: i32,
    y: i32,
    width: i32,
    height: i32,
    cancelled: bool,
}

impl SupportedFormat {
    fn to_image_format(&self) -> ImageFormat {
        match self {
            SupportedFormat::Png => ImageFormat::Png,
            SupportedFormat::Jpeg => ImageFormat::Jpeg,
            SupportedFormat::WebP => ImageFormat::WebP,
            SupportedFormat::Bmp => ImageFormat::Bmp,
            SupportedFormat::Tiff => ImageFormat::Tiff,
        }
    }
    
    fn get_extension(&self) -> &'static str {
        match self {
            SupportedFormat::Png => "png",
            SupportedFormat::Jpeg => "jpg",
            SupportedFormat::WebP => "webp",
            SupportedFormat::Bmp => "bmp",
            SupportedFormat::Tiff => "tiff",
        }
    }
}

/// 生成带时间戳的文件名
fn generate_filename(format: &SupportedFormat) -> String {
    let now = Local::now();
    let timestamp = now.format("%Y%m%d_%H%M%S").to_string();
    format!("screenshot_{}.{}", timestamp, format.get_extension())
}

/// 保存截图
fn save_screenshot(img: &DynamicImage, options: &SaveOptions) -> TResult<ScreenshotResult> {
    let mut result = ScreenshotResult {
        success: true,
        message: "截图成功".to_string(),
        path: None,
        base64_data: None,
    };
    
    let format = options.format.to_image_format();
    
    // 保存到剪贴板
    if options.save_to_clipboard.unwrap_or(false) {
        if let Err(e) = clipboard::save_to_clipboard(img) {
            result.success = false;
            result.message = format!("保存到剪贴板失败: {}", e);
            return Ok(result);
        }
    }
    
    // 保存到文件
    if options.save_to_file.unwrap_or(true) {
        let file_path = if let Some(path) = &options.file_path {
            path.clone()
        } else {
            // 默认保存到桌面
            let desktop = dirs::desktop_dir().unwrap_or_else(|| std::env::current_dir().unwrap());
            desktop.join(generate_filename(&options.format)).to_string_lossy().to_string()
        };
        
        match img_utils::format_to_bytes(img, format) {
            Ok(bytes) => {
                if let Err(e) = save_to_file::save_bytes_to_file(&file_path, &bytes, true) {
                    result.success = false;
                    result.message = format!("保存文件失败: {}", e);
                    return Ok(result);
                }
                result.path = Some(file_path);
            }
            Err(e) => {
                result.success = false;
                result.message = format!("图片格式转换失败: {}", e);
                return Ok(result);
            }
        }
    }
    
    // 生成base64数据
    match img_utils::img_to_base64(img, format) {
        Ok(base64) => result.base64_data = Some(base64),
        Err(_) => {} // base64生成失败不影响主要功能
    }
    
    Ok(result)
}

#[tauri::command]
async fn take_screenshot(save_path: String, window: tauri::Window) -> ScreenshotResult {
    // 隐藏窗口
    let _ = window.hide();
    
    // 等待窗口隐藏
    tokio::time::sleep(tokio::time::Duration::from_millis(300)).await;
    
    let result = match screenshot_to_img(ScreenTarget::Primary) {
        Ok(img) => {
            let options = SaveOptions {
                format: SupportedFormat::Png,
                quality: None,
                hide_window: Some(true),
                mode: Some(ScreenshotMode::Fullscreen),
                region: None,
                save_to_clipboard: Some(false),
                save_to_file: Some(true),
                file_path: Some(save_path),
            };
            
            match save_screenshot(&img, &options) {
                Ok(result) => result,
                Err(e) => ScreenshotResult {
                    success: false,
                    message: format!("截图失败: {}", e),
                    path: None,
                    base64_data: None,
                },
            }
        }
        Err(e) => ScreenshotResult {
            success: false,
            message: format!("截图失败: {}", e),
            path: None,
            base64_data: None,
        },
    };
    
    // 显示窗口
    let _ = window.show();
    
    result
}

#[tauri::command]
async fn take_screenshot_with_format(save_path: String, options: SaveOptions, window: tauri::Window) -> ScreenshotResult {
    // 如果需要隐藏窗口
    if options.hide_window.unwrap_or(false) {
        let _ = window.hide();
        // 等待窗口隐藏
        tokio::time::sleep(tokio::time::Duration::from_millis(300)).await;
    }
    
    let result = match options.mode.as_ref().unwrap_or(&ScreenshotMode::Fullscreen) {
        ScreenshotMode::Fullscreen => {
            match screenshot_to_img(ScreenTarget::Primary) {
                Ok(img) => {
                    let mut save_options = options.clone();
                    save_options.file_path = Some(save_path.clone());
                    match save_screenshot(&img, &save_options) {
                        Ok(mut result) => {
                            if result.path.is_none() {
                                result.path = Some(save_path);
                            }
                            result
                        }
                        Err(e) => ScreenshotResult {
                            success: false,
                            message: format!("截图失败: {}", e),
                            path: None,
                            base64_data: None,
                        },
                    }
                }
                Err(e) => ScreenshotResult {
                    success: false,
                    message: format!("截图失败: {}", e),
                    path: None,
                    base64_data: None,
                },
            }
        }
        ScreenshotMode::Region => {
            if let Some(region) = &options.region {
                match capture_region(region.x, region.y, region.width, region.height) {
                    Ok(img) => {
                        let mut save_options = options.clone();
                        save_options.file_path = Some(save_path.clone());
                        match save_screenshot(&img, &save_options) {
                            Ok(mut result) => {
                                if result.path.is_none() {
                                    result.path = Some(save_path);
                                }
                                result.message = "区域截图成功".to_string();
                                result
                            }
                            Err(e) => ScreenshotResult {
                                success: false,
                                message: format!("区域截图失败: {}", e),
                                path: None,
                                base64_data: None,
                            },
                        }
                    }
                    Err(e) => ScreenshotResult {
                        success: false,
                        message: format!("区域截图失败: {}", e),
                        path: None,
                        base64_data: None,
                    },
                }
            } else {
                ScreenshotResult {
                    success: false,
                    message: "区域截图需要指定区域参数".to_string(),
                    path: None,
                    base64_data: None,
                }
            }
        }
    };
    
    // 如果之前隐藏了窗口，现在显示窗口
    if options.hide_window.unwrap_or(false) {
        let _ = window.show();
    }
    
    result
}



#[tauri::command]
fn get_supported_formats() -> Vec<serde_json::Value> {
    vec![
        serde_json::json!({
            "format": "Png",
            "name": "PNG",
            "extension": "png",
            "supports_quality": false,
            "description": "便携式网络图形格式，支持透明度，无损压缩"
        }),
        serde_json::json!({
            "format": "Jpeg",
            "name": "JPEG",
            "extension": "jpg",
            "supports_quality": true,
            "description": "联合图像专家组格式，有损压缩，文件较小"
        }),
        serde_json::json!({
            "format": "WebP",
            "name": "WebP",
            "extension": "webp",
            "supports_quality": true,
            "description": "Google开发的现代图像格式，压缩率高"
        }),
        serde_json::json!({
            "format": "Bmp",
            "name": "BMP",
            "extension": "bmp",
            "supports_quality": false,
            "description": "位图格式，无压缩，文件较大"
        }),
        serde_json::json!({
            "format": "Tiff",
            "name": "TIFF",
            "extension": "tiff",
            "supports_quality": false,
            "description": "标记图像文件格式，支持多种压缩方式"
        })
    ]
}

#[tauri::command]
async fn start_screen_selection(window: tauri::Window, hide_window: bool) -> Result<(), String> {
    if hide_window {
        // 如果需要隐藏窗口，直接隐藏（截图背景模式）
        window.hide().map_err(|e| e.to_string())?;
    } else {
        // 如果不隐藏窗口，设置为全屏透明窗口实现实时展示
        window.set_fullscreen(true).map_err(|e| e.to_string())?;
        window.set_always_on_top(true).map_err(|e| e.to_string())?;
        // 设置窗口透明度以实现实时屏幕展示效果
        window.set_decorations(false).map_err(|e| e.to_string())?;
    }
    Ok(())
}



#[tauri::command]
async fn finish_screen_selection(window: tauri::Window, hide_window: bool) -> Result<(), String> {
    if hide_window {
        // 如果之前隐藏了窗口，现在显示窗口
        window.show().map_err(|e| e.to_string())?;
    } else {
        // 如果之前是全屏透明模式，恢复窗口正常状态
        window.set_fullscreen(false).map_err(|e| e.to_string())?;
        window.set_always_on_top(false).map_err(|e| e.to_string())?;
        window.set_decorations(true).map_err(|e| e.to_string())?;
    }
    Ok(())
}

#[cfg_attr(mobile, tauri::mobile_entry_point)]
pub fn run() {
    tauri::Builder::default()
        .plugin(tauri_plugin_shell::init())
        .plugin(tauri_plugin_dialog::init())
        .plugin(tauri_plugin_fs::init())
        .invoke_handler(tauri::generate_handler![take_screenshot, take_screenshot_with_format, get_supported_formats, start_screen_selection, finish_screen_selection])
        .run(tauri::generate_context!())
        .expect("error while running tauri application");
}

fn main() {
    run();
}